package cn.yj.core.task.delay.task;

import cn.yj.cgs.dba.entity.vo.TaskVo;
import cn.yj.common.AppExecutor;
import cn.yj.common.Enums;
import cn.yj.common.config.BeanTool;
import cn.yj.commons.utils.StringUtils;
import cn.yj.core.business.service.iservice.IPackageService;
import cn.yj.core.business.service.iservice.ITaskService;
import cn.yj.core.task.delay.AbstractDelayTaskHandler;
import cn.yj.core.task.delay.packages.PackagesHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 永健
 * @since 2021-05-12 15:16
 */
@Component
public class TaskHandler extends AbstractDelayTaskHandler<TaskDelayEntity> {

    private static final Logger log = LoggerFactory.getLogger(TaskHandler.class);

    @Resource
    private ITaskService iTaskService;

    @PostConstruct
    @Override
    public void initTask() {
        List<TaskVo> taskVoList = iTaskService.getTaskByStatus(Enums.TASK.STATUS.no.name(),
                Enums.TASK.UrgentState.normal.name());
        if (!taskVoList.isEmpty()) {
            taskVoList.stream().forEach(taskVo -> add(taskVo));
        }
    }

    private void add(TaskVo taskVo) {
        String taskNo = taskVo.getTaskNo();

        // 到这个点任务还没有人接单的话就失效
        Date effectivTime = taskVo.getEffectivTime();

        // 创建订单后有效时间为 delayTime
        long delayTime = effectivTime.getTime() - System.currentTimeMillis();

        TaskDelayEntity taskDelayEntity = new TaskDelayEntity();
        taskDelayEntity.setCallback(newCallBack());
        taskDelayEntity.setUnique(taskNo).setDelay(delayTime).setTimeUnit(TimeUnit.MILLISECONDS).setTask(() -> {
            Exception error = null;
            try {
                iTaskService.timeOutCancelTask(taskNo);
            } catch (Exception e) {
                error = e;
                log.error(e.getMessage());
            } finally {
                log.info(" The task will be cancelled when no one takes the order：{}", taskDelayEntity.getUnique());
                taskDelayEntity.getCallback().doFinish(error, taskDelayEntity);
            }
        });
        super.execute(taskDelayEntity);
    }

    public static void delayQueue(String taskNo) {
        AppExecutor.exec(()-> {
            TaskVo taskVo = BeanTool.getBean(ITaskService.class).getByTaskNo(taskNo);
            if (StringUtils.isNotNull(taskNo)) {
                if (Enums.TASK.UrgentState.normal.name().equals(taskVo.getUrgentState())) {
                    BeanTool.getBean(TaskHandler.class).add(taskVo);
                }
            }
        });
    }
}
